package com.pp.demo.common.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.security.Key;
import java.util.*;

@Slf4j
@Component
public class JwtUtils {

    private static final long ACCESS_TOKEN_EXPIRE_MINUTES = 120; // 30分钟
    private static final long REFRESH_TOKEN_EXPIRE_DAYS = 7; // 7天

    private final Key key;

    @Autowired
    public JwtUtils(@Value("${jwt.secret}") String encodedSecret) {
        byte[] decodedKey = Base64.getDecoder().decode(encodedSecret);
        if (decodedKey.length < 32) {
            throw new IllegalArgumentException("JWT密钥长度不足，必须至少32字节");
        }
        this.key = Keys.hmacShaKeyFor(decodedKey);
    }

    /**
     * 生成访问令牌
     */
    public String generateAccessToken(String systemId, String systemName) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("systemId", systemId);
        claims.put("systemName", systemName);

        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + ACCESS_TOKEN_EXPIRE_MINUTES * 60 * 1000);

        return Jwts.builder()
                .setClaims(claims)
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(key, SignatureAlgorithm.HS256)
                .compact();
    }

    /**
     * 生成刷新令牌
     */
    public String generateRefreshToken(String systemId) {
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + REFRESH_TOKEN_EXPIRE_DAYS * 24 * 60 * 60 * 1000);

        return Jwts.builder()
                .setId(UUID.randomUUID().toString())
                .setSubject(systemId)
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(key, SignatureAlgorithm.HS256)
                .compact();
    }

    /**
     * 解析JWT令牌
     */
    public Claims parseToken(String token) {
        try {
            return Jwts.parserBuilder()
                    .setSigningKey(key)
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            log.error("解析JWT令牌失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 验证令牌有效性
     */
    public boolean validateToken(String authToken) {
        Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(authToken);
        return true;
    }

    /**
     * 从令牌中获取系统ID
     */
    public String getSystemId(String token) {
        Claims claims = parseToken(token);
        if (claims != null) {
            return (String) claims.get("systemId");
        }
        return null;
    }

    /**
     * 从令牌中获取系统名称
     */
    public String getSystemName(String token) {
        Claims claims = parseToken(token);
        if (claims != null) {
            return (String) claims.get("systemName");
        }
        return null;
    }

    /**
     * 刷新令牌
     */
    public String refreshToken(String accessToken, String refreshToken) {
        try {
            validateToken(refreshToken);
        } catch (Exception e) {
            log.error("验证令牌有效性失败");
            return null;
        }

        Claims claims = parseToken(accessToken);
        if (claims == null) {
            return null;
        }

        String systemId = (String) claims.get("systemId");
        String systemName = (String) claims.get("systemName");

        return generateAccessToken(systemId, systemName);
    }
}
